package org.kl.bpm.notice;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.kl.bf.service.basic.NotifyInfoService;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.utils.ApplicationContextHelper;
import org.kl.bpm.entity.conf.BpmConfNotice;
import org.kl.bpm.entity.conf.BpmMailTemplate;
import org.kl.bpm.service.conf.BpmConfNoticeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TimeoutNotice {
	private static Logger logger = LoggerFactory.getLogger(TimeoutNotice.class);
	public static final int TYPE_ARRIVAL = 0;
	public static final int TYPE_COMPLETE = 1;
	public static final int TYPE_TIMEOUT = 2;

	public void process(DelegateTask delegateTask) {
		String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
		String processDefinitionId = delegateTask.getProcessDefinitionId();
		List<BpmConfNotice> bpmConfNotices = ApplicationContextHelper.getBean(BpmConfNoticeService.class).findByCodeAndProcessDefinitionId(
				taskDefinitionKey, processDefinitionId);
		ProcessDefinition processDefinition = ApplicationContextHelper.getBean(RepositoryService.class).getProcessDefinition(
				processDefinitionId);

		for (BpmConfNotice bpmConfNotice : bpmConfNotices) {
			if (TYPE_TIMEOUT == bpmConfNotice.getType()) {
				processTimeout(delegateTask, bpmConfNotice, processDefinition);
			}
		}
	}

	public void processTimeout(DelegateTask delegateTask, BpmConfNotice bpmConfNotice, ProcessDefinition processDefinition) {
		try {
			Date dueDate = delegateTask.getDueDate();
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dueDate);

			DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
			Duration duration = datatypeFactory.newDuration("-" + bpmConfNotice.getDueDate());
			duration.addTo(calendar);

			Date noticeDate = calendar.getTime();
			Date now = new Date();

			if ((now.getTime() < noticeDate.getTime()) && ((noticeDate.getTime() - now.getTime()) < (60 * 1000))) {
				UserService userService = ApplicationContextHelper.getBean(UserService.class);
				NotifyInfoService notifyInfoService = ApplicationContextHelper.getBean(NotifyInfoService.class);
				TaskEntity taskEntity = new TaskEntity();
				taskEntity.setId(delegateTask.getId());
				taskEntity.setName(delegateTask.getName());
				taskEntity.setAssigneeWithoutCascade(userService.getUser(delegateTask.getAssignee()).getTrueName());
				taskEntity.setVariableLocal("initiator", getInitiator(userService, delegateTask));
				taskEntity.setVariableLocal("processDefinition", processDefinition);
				
				String receiver = bpmConfNotice.getReceiver();
				BpmMailTemplate bpmMailTemplate = bpmConfNotice.getBpmMailTemplate();
				ExpressionManager expressionManager = Context.getProcessEngineConfiguration().getExpressionManager();

				String to = null;

				if ("任务接收人".equals(receiver)) {
					to = userService.getUser(delegateTask.getAssignee()).getTrueName();
				} else if ("流程发起人".equals(receiver)) {
					to = userService.getUser((String) delegateTask.getVariables().get("initiator")).getTrueName();
				} else {
					HistoricProcessInstanceEntity historicProcessInstanceEntity = Context.getCommandContext()
							.getHistoricProcessInstanceEntityManager().findHistoricProcessInstance(delegateTask.getProcessInstanceId());
					to = userService.getUser(historicProcessInstanceEntity.getStartUserId()).getTrueName();
				}

				String subject = expressionManager.createExpression(bpmMailTemplate.getSubject()).getValue(taskEntity).toString();

				String content = expressionManager.createExpression(bpmMailTemplate.getContent()).getValue(taskEntity).toString();
				try {
					notifyInfoService.sendNotice(to, subject, content);
				} catch (Exception e) {
					logger.info("任务超时提醒邮件发送失败：" + e.getMessage());
					e.printStackTrace();
				}
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
	}

	public String getInitiator(UserService userService, DelegateTask delegateTask) {
		return userService.getUser((String) delegateTask.getVariables().get("initiator")).getTrueName();
	}
}
